package com.candoit.webapps.pricing.controllers;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;

import com.candoit.webapps.pricing.model.MateriaPrima;
import com.candoit.webapps.pricing.model.TipoMateriaPrima;
import com.candoit.webapps.pricing.util.MateriaPrimaUtil;
import com.candoit.webapps.pricing.util.QueryUtil;

@ManagedBean(name = "matPrimaCtrl")
@ViewScoped
public class MateriaPrimaController extends AbstractController {
	
	private List<MateriaPrimaUtil> materias;
	
	private MateriaPrima matPrimaSelected;
	
	Map<Integer, MateriaPrimaUtil> map;
	
	private UploadedFile archivo;
	
	
	public List<MateriaPrimaUtil> getMaterias() {
		if (materias == null){
			List<MateriaPrima> materiasList = QueryUtil.getInstance().getMateriasPrimas();
			this.llenarMaterias(materiasList);
		}
		return materias;
	}
	
	public void setMaterias(List<MateriaPrimaUtil> materias) {
		this.materias = materias;
	}

	public MateriaPrima getMatPrimaSelected() {
		if (matPrimaSelected == null){
			matPrimaSelected = new MateriaPrima();
		}
		return matPrimaSelected;
	}

	public void setMatPrimaSelected(MateriaPrima matPrimaSelected) {
		this.matPrimaSelected = matPrimaSelected;
	}

	public void saveMateriaPrima(){
		if (matPrimaSelected.getNombre()== null || matPrimaSelected.getNombre().equals("")){
			FacesContext.getCurrentInstance().addMessage("savematprimform:nombre", new FacesMessage(NAME_MP_EMPTY));
			this.error = true;
		}
		if (this.error){
			return;
		}
		
		this.save(matPrimaSelected);
		
		matPrimaSelected = null;
	}
	
	public void removeMateriaPrima(){
		this.remove(matPrimaSelected);
		matPrimaSelected = null;
	}
	
	public void clearData(){
		this.saveSuccess = false;
		this.deleteSuccess = false;
		this.matPrimaSelected = null;
	}
	
	private void llenarMaterias(List<MateriaPrima> list){
		map = new HashMap<Integer, MateriaPrimaUtil>();
		materias = new ArrayList<MateriaPrimaUtil>();
		for(MateriaPrima materia : list){
			MateriaPrimaUtil util = new MateriaPrimaUtil();
			if (materia.getCostoSimulado() == null){
				materia.setCostoSimulado(materia.getCostoUnitario());
			}
			if (materia.getTipoMateriaPrima() == null){
				TipoMateriaPrima tipo = QueryUtil.getInstance().getTipoMateriaPrimaById(TipoMateriaPrima.PAPEL);
				materia.setTipoMateriaPrima(tipo);
			}
			util.setMateria(materia);
			util.setChanged(false);
			util.setCostoSimulado(materia.getCostoSimulado());
			util.setCostoReal(materia.getCostoUnitario());
			util.setDescripcion(materia.getNombre());
			util.setGramaje(materia.getGramaje());
			util.setTipo(materia.getTipoMateriaPrima());
			util.setUnidad(materia.getUnidad());
			util.setActivo(materia.isActivo());
			if (!map.containsKey(materia.getId())){
				map.put(materia.getId(), util);
			}
			materias.add(util);
		}
		
		MateriaPrima materiaNueva = new MateriaPrima();
		MateriaPrimaUtil matUtilNuevo = new MateriaPrimaUtil();
		matUtilNuevo.setMateria(materiaNueva);
		matUtilNuevo.setChanged(false);
		matUtilNuevo.setCostoSimulado(0.00d);
		matUtilNuevo.setDescripcion("");
		matUtilNuevo.setActivo(true);
		materias.add(matUtilNuevo);
	}
	
	public void importar(){
		if (archivo != null){	
			try {
				POIFSFileSystem fs = new POIFSFileSystem(archivo.getInputStream()); 
				HSSFWorkbook  wb =new HSSFWorkbook(fs);
				Sheet sheet =  wb.getSheet("COSTOS M.P.");
				if (sheet != null){
				  for (int i = 2; i < sheet.getLastRowNum()-1; i++) {
					if (sheet.getRow(i) != null && sheet.getRow(i).getCell(0) != null && sheet.getRow(i).getCell(0).getStringCellValue() != null
							&& !sheet.getRow(i).getCell(0).getStringCellValue().equals("") 
							&& (sheet.getRow(i).getCell(4) != null )
							&& (sheet.getRow(i).getCell(4).getCellType() != Cell.CELL_TYPE_BLANK )
							&& (sheet.getRow(i).getCell(4).getCellType() == Cell.CELL_TYPE_NUMERIC || sheet.getRow(i).getCell(4).getCellType() == Cell.CELL_TYPE_FORMULA )){
						String cuentaNombre = sheet.getRow(i).getCell(0).getStringCellValue().trim();
						double costo = sheet.getRow(i).getCell(4).getNumericCellValue();
						String descTipo = sheet.getRow(i).getCell(5).getStringCellValue();
						TipoMateriaPrima tipo = QueryUtil.getInstance().getTipoMateriaPrimaByDesc(descTipo);
						if (tipo != null){
							MateriaPrima materia = null;
							try{	
								materia = QueryUtil.getInstance().getMateriaByDescriptionAndTipo(cuentaNombre, tipo);
							}catch(Exception e){}
							if (materia == null){
								materia = new MateriaPrima();
								materia.setNombre(cuentaNombre);
								materia.setCostoUnitario(costo);
								materia.setCostoSimulado(costo);
								materia.setTipoMateriaPrima(tipo);
								this.save(materia);
								MateriaPrimaUtil util = new MateriaPrimaUtil();
								util.setMateria(materia);
								util.setChanged(true);
								materias.add(util);
								map.put(materia.getId(), util);
					 }else{
						 	MateriaPrimaUtil util = map.get(materia.getId());
						 	double costoMp = util.getMateria().getCostoUnitario();
						 	String val = costoMp+"";
						 	BigDecimal big = new BigDecimal(val);
						 	big = big.setScale(4, RoundingMode.HALF_UP);
						 	String valXls = costo+"";
						 	BigDecimal bigXls = new BigDecimal(valXls);
						 	bigXls = bigXls.setScale(4, RoundingMode.HALF_UP);
						 	if (big.compareTo(bigXls) != 0){
						 		util.setChanged(true);
						 		util.getMateria().setCostoUnitario(costo);
						 		util.setCostoSimulado(util.getMateria().getCostoUnitario());
						 		this.update(util.getMateria());
						 	}else{
						 		util.setChanged(false);
						 	}
					 }
				 }
			  }	 
		   }
	   }else{
		   FacesContext.getCurrentInstance().addMessage("abmmatprimform:botonImportar", new FacesMessage("No encontró la hoja de calculo con nombre 'COSTOS M.P.'"));
			return;
	   }

		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage("abmmatprimform:botonImportar", new FacesMessage("Error al importar los datos"));
			return;
		}
		}
	}
	
	public void actualizar(){
		Iterator<MateriaPrimaUtil> it = materias.iterator();
		while(it.hasNext()){
			MateriaPrimaUtil util = (MateriaPrimaUtil)it.next();
			if (util.getMateria().getId() != null){
				util.getMateria().setCostoSimulado(util.getCostoSimulado());
				util.getMateria().setCostoUnitario(util.getCostoReal());
				util.getMateria().setGramaje(util.getGramaje());
				util.getMateria().setNombre(util.getDescripcion());
				util.getMateria().setTipoMateriaPrima(util.getTipo());
				util.getMateria().setUnidad(util.getUnidad());
				util.getMateria().setActivo(util.isActivo());
				this.update(util.getMateria());
			}else{
				if (!util.getDescripcion().equals("")){
					util.getMateria().setCostoSimulado(util.getCostoSimulado());
					util.getMateria().setCostoUnitario(util.getCostoReal());
					util.getMateria().setGramaje(util.getGramaje());
					util.getMateria().setNombre(util.getDescripcion());
					util.getMateria().setTipoMateriaPrima(util.getTipo());
					util.getMateria().setUnidad(util.getUnidad());
					util.getMateria().setCostoUnitario(util.getCostoSimulado());
					util.getMateria().setActivo(util.isActivo());
					this.save(util.getMateria());
				}
			}
		}
		
		FacesContext.getCurrentInstance().renderResponse();
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("admin-mp.jsf");
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	public void simular(){
		Iterator<MateriaPrimaUtil> it = materias.iterator();
		while(it.hasNext()){
			MateriaPrimaUtil util = (MateriaPrimaUtil)it.next();
			if (!util.getDescripcion().equals("")){
				util.getMateria().setCostoUnitario(util.getCostoSimulado());
				util.getMateria().setCostoSimulado(util.getCostoSimulado());
				this.update(util.getMateria());
			}
		}
		
		FacesContext.getCurrentInstance().renderResponse();
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("admin-mp.jsf");
		} catch (IOException e) {
			e.printStackTrace();
		}	
		
	}
	
	public void borrarMaterias(){
		Iterator<MateriaPrimaUtil> it = materias.iterator();
		while(it.hasNext()){
			MateriaPrimaUtil util = (MateriaPrimaUtil)it.next();
			if (util.isSelected()){	
				this.remove(util.getMateria());
			}	
		}
		
		FacesContext.getCurrentInstance().renderResponse();
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("admin-mp.jsf");
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	

	public UploadedFile getArchivo() {
		return archivo;
	}

	public void setArchivo(UploadedFile archivo) {
		this.archivo = archivo;
	}
	
	
}
